package com.iflytek.autofly.setting.biz.sound;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemProperties;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CompoundButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.iflytek.autofly.audioservice.aidl.Balance;
import com.iflytek.autofly.audioservice.util.AudioServiceCons;
import com.iflytek.autofly.setting.R;
import com.iflytek.autofly.setting.biz.base.BaseFragment;
import com.iflytek.autofly.setting.biz.base.CommonRadioButtonBean;
import com.iflytek.autofly.setting.biz.base.CommonRadioGroupAdpt;
import com.iflytek.autofly.setting.util.FlySettings;
import com.iflytek.autofly.setting.util.SpUtil;
import com.iflytek.autofly.setting.widget.InnerListView;
import com.iflytek.autofly.setting.widget.VerticalSeekBar;
import com.iflytek.autofly.utils.FlyLog;
import com.iflytek.sunflower.FlowerCollector;

import java.lang.ref.WeakReference;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * <b>Description: </b>声音设置的fragment<br/>
 * <b>Change History:</b><br/>
 * <table border="1">
 * <tr>
 * <td><b>user</b></td>
 * <td><b>date</b></td>
 * <td><b>time</b></td>
 * <td><b>reason</b></td>
 * </tr>
 * <tr>
 * <td>JunLuan@iflytek.com</td>
 * <td>2015年10月14日</td>
 * <td>上午11:34:14</td>
 * <td>创建此文件</td>
 * </tr>
 * </table>
 *
 * @author JunLuan@iflytek.com
 */
public class SoundFragment extends BaseFragment implements FlyAudioManager.IFlyAudioListener {
    protected static final String TAG = "SoundFragment";
    private static final String PROPERTY_NOTIFICATIUON_RING = "persist.sys.autofly.noti_ring";
    private static final String[] CMD = {"notice", "key", "mix", "ich", "volume", "eq", "balance", "vos"};

    private static final String SP_EQ_NAME = "volume_eq";
    private static final String SP_BALANCE_NAME = "volume_balance";
    private static final int MSG_BALANCE_UI_USER_TOUCH = 0x1001;
    private View mView;

    private ToggleButton mNoticeRingTbn;
    private ToggleButton mKeyRingTbn;
    private TextView mMixValueTv;
    private InnerListView mMixListView;
    private TextView mIncomingCallHintTv;
    private InnerListView mIchintListView;
    private SeekBar mCallVolumeSb;
    private SeekBar mOtherVolumeSb;
    private TextView mCallVolumeTv;
    private TextView mOtherVolumeTv;
    private TextView mEqModeValueTv;
    private LinearLayout mEqBandsLayer;
    private InnerListView mEqModeLv;
    private VerticalSeekBar[] mEqBandsSb;
    private TextView mBalanceValTv;
    private InnerListView mBalanceBestLv;
    private BalancePanel mBalancePanel;
    private ToggleButton mSpeedEnhanceTbn;

    private FlyAudioManager mFlyAudioManager;
    private AtomicInteger mServiceReady = new AtomicInteger(0);
    private int mEqValMin;
    private int mBalanceMinVal = -10;
    private int mBalanceMaxVal = 10;
    private int[][] mBalanceBestPosition;
    private int mBalanceLogicX;
    private int mBalanceLogicY;
    private int mBandCount;

    private UIHandler mHandler = new UIHandler(this);
    private ToggleButton mMuteOnScreenOffTbn;
    private ToggleButton mMuteOnReverseTbn;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = super.onCreateView(inflater, container, savedInstanceState);
        mView = view;
        init(view);
        return view;
    }

    @Override
    public void onDestroyView() {
        synchronized (this) {
            FlyAudioManager.unregisterListener(this);
            mEqBandsSb = null;
        }
        mServiceReady.set(0);
        mFlyAudioManager = null;
        super.onDestroyView();
    }

    private void init(View v) {
        addUnit(R.layout.noticering);
        addUnit(R.layout.keyring);
        addUnit(R.layout.soundmix, R.layout.soundmix_sub, new OnExpandChangeListener() {
            @Override
            public void onExpandChanged(boolean isExpanded) {
                if (isExpanded) {
                    mMixValueTv.setVisibility(View.GONE);
                } else {
                    mMixValueTv.setVisibility(View.VISIBLE);
                }
            }
        }, null);
        addHiddenUnit(R.layout.incomingcallhint, R.layout.incomingcallhint_sub, new OnExpandChangeListener() {
            @Override
            public void onExpandChanged(boolean isExpanded) {
                if (isExpanded) {
                    mIncomingCallHintTv.setVisibility(View.GONE);
                } else {
                    mIncomingCallHintTv.setVisibility(View.VISIBLE);
                }
            }
        }, null);
        addUnit(R.layout.volume, R.layout.volume_sub, new OnExpandChangeListener() {
            @Override
            public void onExpandChanged(boolean isExpanded) {
                TextView descTv = (TextView) mView.findViewById(R.id.snd_volume_desc_tv);
                if (isExpanded) {
                    descTv.setVisibility(View.GONE);
                } else {
                    descTv.setVisibility(View.VISIBLE);
                }
            }
        }, null);
        addUnit(R.layout.eq, R.layout.eq_sub, new OnExpandChangeListener() {
            @Override
            public void onExpandChanged(boolean isExpanded) {
                TextView descTv = (TextView) mView.findViewById(R.id.snd_eq_desc_tv);
                if (isExpanded) {
                    mEqModeValueTv.setVisibility(View.GONE);
                    descTv.setVisibility(View.GONE);
                } else {
                    mEqModeValueTv.setVisibility(View.VISIBLE);
                    descTv.setVisibility(View.VISIBLE);
                }
            }
        }, null);
        addUnit(R.layout.balance, R.layout.balance_sub, new OnExpandChangeListener() {
            @Override
            public void onExpandChanged(boolean isExpanded) {
                TextView descTv = (TextView) mView.findViewById(R.id.snd_balance_desc_tv);
                if (isExpanded) {
                    mBalanceValTv.setVisibility(View.GONE);
                    descTv.setVisibility(View.GONE);
                } else {
                    mBalanceValTv.setVisibility(View.VISIBLE);
                    descTv.setVisibility(View.VISIBLE);
                }
            }
        }, null);
        addUnit(R.layout.speedenhance);
        addUnit(R.layout.muteonscreenoff);
        addUnit(R.layout.muteonreverse);

        initNoticeRingView(v);
        initKeyRingView(v);
        initMixView(v);
        initInCallHintView(v);
        initVolumeView(v);
        initEqView(v);
        initBalanceView(v);
        initSpeedEnhanceView(v);
        initMuteOnScreenOffView(v);
        initMuteOnReverseView(v);

        mFlyAudioManager = FlyAudioManager.registerListener(getActivity(), this);
    }


    @Override
    public void onServiceConnected(boolean succeed) {
        if (succeed) {
            FlyLog.d(TAG, "onServiceConnected succeed");
            renew();
        } else {
            FlyLog.e(TAG, "onServiceConnected failed");
        }
    }

    @Override
    public void onMediaVolumeChanged(int value) {
    }

    @Override
    public void onCallVolumeChanged(int value) {
        final int v = value;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateVolumeUI(mCallVolumeTv, mCallVolumeSb, v);
            }
        });
    }

    @Override
    public void onTipVolumeChanged(int value) {
    }

    @Override
    public void onDefaultVolumeChanged(int value) {
        final int v = value;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateVolumeUI(mOtherVolumeTv, mOtherVolumeSb, v);
            }
        });
    }

    @Override
    public void onNaviVolumeChanged(int value) {
    }

    @Override
    public void onLoudnessCompensationStateChanged(boolean enabled) {
    }

    @Override
    public void onEqChanged(int idx, int v) {
        final int index = idx;
        final int value = v;
        FlyLog.d(TAG, "index:" + index + " value:" + value);
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateEqBandUI(index, value);
            }
        });
    }

    @Override
    public void onBalaceChanged(int balance, int fade) {
        mBalanceLogicX = balance;
        mBalanceLogicY = fade;
        getActivity().runOnUiThread(new Runnable() {
            public void run() {
                updateBalanceUI(true);
            }
        });
    }

    @Override
    public void onEQModeChanged(int mode) {
        final int mod = mode;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateEqModeUI(mod);
            }
        });
    }

    @Override
    public void onMixModeChanged(FlyAudioManager.MixMode mode) {
        final FlyAudioManager.MixMode mod = mode;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateMixUI(mod);
            }
        });
    }

    @Override
    public void onInCallHintModeChanged(FlyAudioManager.InCallHintMode mode) {
        final FlyAudioManager.InCallHintMode mod = mode;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                updateInCallHintUI(mod);
            }
        });
    }

    @Override
    public void onSpeedEnhanceModeChanged(boolean isOn) {
        final boolean on = isOn;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mSpeedEnhanceTbn.setChecked(on);
            }
        });
    }

    @Override
    public void onNoticeRingChanged(boolean isOn) {
        final boolean on = isOn;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mNoticeRingTbn.setChecked(on);
            }
        });

    }

    @Override
    public void onKeyRingChanged(boolean isOn) {
        final boolean on = isOn;
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mKeyRingTbn.setChecked(on);
            }
        });
    }

    @Override
    public void onMuteOnScreenOffChanged(final boolean state) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mMuteOnScreenOffTbn.setChecked(state);
            }
        });
    }

    @Override
    public void onMuteOnReverse(final boolean state) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mMuteOnReverseTbn.setChecked(state);
            }
        });
    }

    @Override
    public void processCommandline(final String cmd) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                FlyLog.d(TAG, "cmd=" + cmd);
                switch (cmd) {
                    case "volume_open":
                        //expand(0);
                        break;
                    default:
                        FlyLog.w(TAG, "unknown cmd:" + cmd);
                }

            }
        }).start();

    }

    @Override
    public String[] getCommands() {
        return CMD;
    }

    public void renew() {
        if (mServiceReady.incrementAndGet() < 3) {
            return;
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 逻辑和界面更新分开，提速
                if (mFlyAudioManager == null) {
                    return;
                }
                final FlyAudioManager audioMngr = mFlyAudioManager;
                final boolean noticeRingState = SystemProperties.getBoolean(PROPERTY_NOTIFICATIUON_RING, true);
                final boolean keyRingState = audioMngr.isKeyRingEnabled();
                final FlyAudioManager.MixMode mixMode = audioMngr.getMixMode();
                final FlyAudioManager.InCallHintMode icHintMode = audioMngr.getIncomingCallHintMode();
                final int maxCallVolume = audioMngr.getMaxCallVolume();
                final int callVolume = audioMngr.getCallVolume();
                final int maxOtherVolume = audioMngr.getMaxDefaultVolume();
                final int defaultVolume = audioMngr.getDefaultVolume();
                mEqValMin = audioMngr.getEQMinVal();
                final int valMax = audioMngr.getEQMaxVal();
                final int eqValRange = valMax - mEqValMin;
                mBandCount = audioMngr.getEQBandCount();
                if (mBandCount <= 0) {
                    mBandCount = 0;
                }
                final int eqMode = audioMngr.getEQMode();
                mBalanceMaxVal = audioMngr.getBalanceMax();
                mBalanceMinVal = audioMngr.getBalanceMin();
                mBalancePanel.setRange(mBalanceMinVal, mBalanceMaxVal);
                if (mBalanceBestPosition == null) {
                    mBalanceBestPosition = new int[5][2];
                    mBalanceBestPosition[0][0] = 0;
                    mBalanceBestPosition[0][1] = 0;
                    mBalanceBestPosition[1][0] = mBalanceMinVal / 2;
                    mBalanceBestPosition[1][1] = mBalanceMinVal / 2;
                    mBalanceBestPosition[2][0] = mBalanceMaxVal / 2;
                    mBalanceBestPosition[2][1] = mBalanceMinVal / 2;
                    mBalanceBestPosition[3][0] = mBalanceMinVal / 2;
                    mBalanceBestPosition[3][1] = mBalanceMaxVal / 2;
                    mBalanceBestPosition[4][0] = mBalanceMaxVal / 2;
                    mBalanceBestPosition[4][1] = mBalanceMaxVal / 2;
                }
                final Balance balance = audioMngr.getBalance();
                final boolean speedEnhanceState = audioMngr.isSpeedEnhanceOn();
                final boolean muteOnScreenState = audioMngr.isMuteOnScreenOff();
                final boolean muteOnReverse = audioMngr.isMuteOnReverse();

                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mNoticeRingTbn.setChecked(noticeRingState);
                        mKeyRingTbn.setChecked(keyRingState);
                        updateMixUI(mixMode);
                        updateInCallHintUI(icHintMode);
                        mCallVolumeSb.setMax(maxCallVolume);
                        updateVolumeUI(mCallVolumeTv, mCallVolumeSb, callVolume);
                        mOtherVolumeSb.setMax(maxOtherVolume);
                        updateVolumeUI(mOtherVolumeTv, mOtherVolumeSb, defaultVolume);
                        showEqTextView(mEqValMin, R.id.snd_eq_ruler_min_tv, mView);
                        showEqTextView(valMax, R.id.snd_eq_ruler_max_tv, mView);
                        showEqTextView((mEqValMin + valMax) / 2, R.id.snd_eq_ruler_mid_tv, mView);

                        if (mEqBandsSb == null) {
                            mEqBandsSb = new VerticalSeekBar[mBandCount];
                            EQOnSeekBarChangeListener[] eqOnSeekBarChangeListener = new EQOnSeekBarChangeListener[mBandCount];
                            List<String> bandNames = audioMngr.getEQBandNames();

                            for (int i = 0; i < mBandCount; i++) {
                                LinearLayout ll = (LinearLayout) getActivity().getLayoutInflater().inflate(
                                        R.layout.snd_eq_seekbar, null);

                                mEqBandsSb[i] = (VerticalSeekBar) ll
                                        .findViewById(R.id.vertical_seekbar);
                                mEqBandsSb[i].setMax(eqValRange);
                                eqOnSeekBarChangeListener[i] = new EQOnSeekBarChangeListener();
                                eqOnSeekBarChangeListener[i].setBandIndex(i);
                                mEqBandsSb[i]
                                        .setOnSeekBarChangeListener(eqOnSeekBarChangeListener[i]);

                                if (bandNames != null && i < bandNames.size()
                                        && bandNames.get(i) != null) {
                                    TextView tv = (TextView) ll
                                            .findViewById(R.id.vertical_seekbar_label);
                                    tv.setText(bandNames.get(i));
                                }

                                mEqBandsLayer.addView(ll);
                            }
                        }
                        audioMngr.getEQ();
                        mEqModeLv.setItemChecked(eqModeToListIdx(eqMode), true);
                        mEqModeValueTv.setText(eqModeToResId(eqMode));

                        if (balance != null) {
                            mBalanceLogicX = balance.getBal();
                            mBalanceLogicY = balance.getFade();
                        } else {
                            mBalanceLogicX = Settings.Global.getInt(getActivity().getContentResolver(),
                                    FlySettings.Sound.BALANCE_BAL, 0);
                            mBalanceLogicY = Settings.Global.getInt(getActivity().getContentResolver(),
                                    FlySettings.Sound.BALANCE_FADE, 0);
                        }
                        updateBalanceUI(true);
                        mSpeedEnhanceTbn.setChecked(speedEnhanceState);
                        mMuteOnScreenOffTbn.setChecked(muteOnScreenState);
                        mMuteOnReverseTbn.setChecked(muteOnReverse);
                    }
                });
            }
        }).start();
    }

    private void initNoticeRingView(View v) {
        mNoticeRingTbn = (ToggleButton) v.findViewById(R.id.snd_noticering_switch_tbn);
        mNoticeRingTbn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_noticering), "" + isChecked);
                boolean value = SystemProperties.getBoolean(PROPERTY_NOTIFICATIUON_RING, true);
                if (value != isChecked) {
                    SystemProperties.set(PROPERTY_NOTIFICATIUON_RING, String.valueOf(isChecked));
                    getActivity().sendBroadcast(new Intent("com.iflytek.autofly.NOTIFI_RING_PROPERTY"));
                }
            }
        });
        mNoticeRingTbn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
    }

    private void initKeyRingView(View v) {
        mKeyRingTbn = (ToggleButton) v.findViewById(R.id.snd_keyring_switch_tbn);
        mKeyRingTbn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_keyring_event), "" + isChecked);
                if (mFlyAudioManager != null) {
                    mFlyAudioManager.setKeyRing(isChecked);
                }
            }
        });
        mKeyRingTbn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            }
        });
    }

    private void initMixView(View v) {
        mMixValueTv = (TextView) v.findViewById(R.id.snd_mix_value_tv);
        mMixListView = (InnerListView) v.findViewById(R.id.snd_mix_listview);
        CommonRadioGroupAdpt mixListAdpt = new CommonRadioGroupAdpt(getActivity());
        mixListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_mix_navi_first), getString(R.string.snd_mix_navi_first_desc), R.string.snd_mix_navi_first));
        mixListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_mix_normal), getString(R.string.snd_mix_normal_desc), R.string.snd_mix_normal));
        mMixListView.setAdapter(mixListAdpt);
        mMixValueTv.setText(getString(R.string.snd_mix_navi_first));
        mMixListView.setItemChecked(0, true);
        mMixListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_mix), getString((int) id));
                mMixValueTv.setText(getString((int) id));
                switch ((int) id) {
                    case R.string.snd_mix_normal:
                        mFlyAudioManager.setMixMode(FlyAudioManager.MixMode.NORMAL);
                        break;
                    case R.string.snd_mix_navi_first:
                        mFlyAudioManager.setMixMode(FlyAudioManager.MixMode.NAVI_FIRST);
                        break;
                }
            }
        });
    }

    private void initInCallHintView(View v) {
        mIncomingCallHintTv = (TextView) v.findViewById(R.id.snd_ichint_value_tv);
        mIchintListView = (InnerListView) v.findViewById(R.id.snd_ichint_listview);
        CommonRadioGroupAdpt ichintListAdpt = new CommonRadioGroupAdpt(getActivity());
        ichintListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_ichint_tts), R.string.snd_ichint_tts));
        ichintListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_ichint_sys), R.string.snd_ichint_sys));
        mIchintListView.setAdapter(ichintListAdpt);
        mIchintListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_incomingcallhint), getString((int) id));
                mIncomingCallHintTv.setText(getString((int) id));
                switch ((int) id) {
                    case R.string.snd_ichint_tts:
                        mFlyAudioManager.setInCallHintMode(FlyAudioManager.InCallHintMode.TTS);
                        break;
                    case R.string.snd_ichint_sys:
                        mFlyAudioManager.setInCallHintMode(FlyAudioManager.InCallHintMode.SYS);
                        break;
                }
            }
        });
    }

    private void initVolumeView(View v) {
        mCallVolumeSb = (SeekBar) v.findViewById(R.id.snd_volume_call_sb);
        mOtherVolumeSb = (SeekBar) v.findViewById(R.id.snd_volume_other_sb);
        mCallVolumeTv = (TextView) v.findViewById(R.id.snd_volume_call_value_tv);
        mOtherVolumeTv = (TextView) v.findViewById(R.id.snd_volume_other_value_tv);

        mCallVolumeSb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            boolean mPressed = false;

            @Override
            public void onProgressChanged(SeekBar sb,
                                          int progress, boolean fromUser) {
                if (!mPressed) {
                    return;
                }
                if (mServiceReady.get() >= 2 && mFlyAudioManager != null) {
                    mFlyAudioManager.setCallVolume(progress);
                }
                mCallVolumeTv.setText(Integer.toString(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar sb) {
                mPressed = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar sb) {
                mPressed = false;
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_volume_call_label), "" + mCallVolumeSb.getProgress());
            }

        });
        mOtherVolumeSb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            boolean mPressed = false;

            @Override
            public void onProgressChanged(SeekBar sb, int progress, boolean fromUser) {
                if (!mPressed) {
                    return;
                }
                if (mServiceReady.get() >= 2 && mFlyAudioManager != null) {
                    mFlyAudioManager.setDefaultVolume(progress);
                }
                mOtherVolumeTv.setText(Integer.toString(progress));
            }

            @Override
            public void onStartTrackingTouch(SeekBar sb) {
                mPressed = true;
            }

            @Override
            public void onStopTrackingTouch(SeekBar sb) {
                mPressed = false;
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_volume_other_label), "" + mOtherVolumeSb.getProgress());
            }

        });
//        mOtherVolumeTv.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View v) {
//                if (mFlyAudioManager.getMuteState()) {
//                    mFlyAudioManager.unMute();
//                } else {
//                    mFlyAudioManager.mute();
//                }
//            }
//        });
    }

    private void initEqView(View v) {
        mEqModeValueTv = (TextView) v.findViewById(R.id.snd_eq_value_tv);
        mEqModeLv = (InnerListView) v.findViewById(R.id.snd_eq_mode_lv);

        mEqModeLv = (InnerListView) v.findViewById(R.id.snd_eq_mode_lv);
        CommonRadioGroupAdpt eqModeListAdpt = new CommonRadioGroupAdpt(getActivity());
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_default), R.string.snd_eq_mode_default));
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_jaz), R.string.snd_eq_mode_jaz));
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_classic), R.string.snd_eq_mode_classic));
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_pop), R.string.snd_eq_mode_pop));
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_rock), R.string.snd_eq_mode_rock));
        eqModeListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_eq_mode_custom), R.string.snd_eq_mode_custom));
        mEqModeLv.setAdapter(eqModeListAdpt);
        mEqModeLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                int index = eqResIdToMode((int) id);
                if (index != AudioServiceCons.EQ_MODE.EQ_MODE_USER) {
                    FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_eq), getString((int) id));
                    mFlyAudioManager.setEQMode(index);
                } else {
                    // 自定义
                    restoreCustomEq();
                }
            }

        });

        mEqBandsLayer = (LinearLayout) v.findViewById(R.id.ll_eq_bands);
        addFreezeView(mEqBandsLayer);
    }

    private void restoreCustomEq() {
        for (int i = 0; i < mBandCount; i++) {
            int value = SpUtil.getInt(getActivity(), SP_EQ_NAME, "" + i, 0);
            if (mFlyAudioManager != null) {
                FlyLog.d(TAG, "band=" + i + ",value=" + value);
                mFlyAudioManager.setEQ(i, value);
            }
        }
        if (mFlyAudioManager != null) {
            mFlyAudioManager.setEQMode(AudioServiceCons.EQ_MODE.EQ_MODE_USER);
            mFlyAudioManager.getEQ();
        }
    }

    private void saveCustomEq() {
        if (mFlyAudioManager != null) {
            for (int i = 0; i < mBandCount; i++) {
                int value = mFlyAudioManager.getEQ(i);
                FlyLog.d(TAG, "band=" + i + ",value=" + value);
                SpUtil.saveInt(getActivity(), SP_EQ_NAME, "" + i, value);
            }
        }
    }

    private void initBalanceView(View v) {
        mBalancePanel = (BalancePanel) v.findViewById(R.id.snd_balance_panel);
        mBalancePanel.setRangeId(R.drawable.snd_balance_pannel);
        mBalancePanel.setXId(R.drawable.snd_balance_cross_x);
        mBalancePanel.setYId(R.drawable.snd_balance_cross_y);
        mBalancePanel.setCrossDotId(R.drawable.snd_balance_lock_dot);
        mBalancePanel.setOnTouchListener(new BalancePanel.OnTouchListener() {
            @Override
            public boolean onTouch(final int x, final int y, final int action) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        if (action == MotionEvent.ACTION_UP) {
                            FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_balance), "pannel");
                            mBalanceLogicX = x;
                            mBalanceLogicY = y;
                            mFlyAudioManager.setBalance(x, y);
                            saveCustomBalance(mBalanceLogicX, mBalanceLogicY);
                            Message msg = new Message();
                            msg.what = MSG_BALANCE_UI_USER_TOUCH;
                            msg.arg1 = x;
                            msg.arg2 = y;
                            mHandler.removeMessages(MSG_BALANCE_UI_USER_TOUCH);
                            mHandler.sendMessage(msg);
                        }
                    }
                }).start();
                return false;
            }
        });
        addFreezeView(mBalancePanel);

        mBalanceBestLv = (InnerListView) v.findViewById(R.id.snd_balance_best_position_lv);
        CommonRadioGroupAdpt balanceBestListAdpt = new CommonRadioGroupAdpt(getActivity());
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_center_best), R.string.snd_balance_center_best));
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_lf_best), R.string.snd_balance_lf_best));
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_rf_best), R.string.snd_balance_rf_best));
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_lr_best), R.string.snd_balance_lr_best));
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_rr_best), R.string.snd_balance_rr_best));
        balanceBestListAdpt.addItem(new CommonRadioButtonBean(getString(R.string.snd_balance_custom), R.string.snd_balance_custom));
        mBalanceBestLv.setAdapter(balanceBestListAdpt);
        mBalanceBestLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_balance), getString((int) id));
                if (id != R.string.snd_balance_custom) {
                    mBalanceLogicX = mBalanceBestPosition[position][0];
                    mBalanceLogicY = mBalanceBestPosition[position][1];
                    mFlyAudioManager.setBalance(mBalanceLogicX, mBalanceLogicY);
                } else {
                    restoreCustomBalance();
                }
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        updateBalanceUIByBest(position);
                    }
                });
                Settings.Global.putInt(getActivity().getContentResolver(), FlySettings.Sound.BALANCE_BAL, mBalanceLogicX);
                Settings.Global.putInt(getActivity().getContentResolver(), FlySettings.Sound.BALANCE_FADE, mBalanceLogicY);
            }
        });

        mBalanceValTv = (TextView) v.findViewById(R.id.snd_balance_value_tv);

    }

    private void restoreCustomBalance() {
        mBalanceLogicX = SpUtil.getInt(getActivity(), SP_BALANCE_NAME, "balance", 0);
        mBalanceLogicY = SpUtil.getInt(getActivity(), SP_BALANCE_NAME, "fade", 0);
        if (mFlyAudioManager != null) {
            mFlyAudioManager.setBalance(mBalanceLogicX, mBalanceLogicY);
        }
    }

    private void saveCustomBalance(int balance, int fade) {
        SpUtil.saveInt(getActivity(), SP_BALANCE_NAME, "balance", balance);
        SpUtil.saveInt(getActivity(), SP_BALANCE_NAME, "fade", fade);
    }

    private void initSpeedEnhanceView(View v) {
        mSpeedEnhanceTbn = (ToggleButton) v.findViewById(R.id.snd_se_switch_tbn);
        mSpeedEnhanceTbn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mSpeedEnhanceTbn.isChecked()) {
                    mFlyAudioManager.turnOnSpeedEnhance();
                } else {
                    mFlyAudioManager.turnOffSpeedEnhance();
                }
            }
        });
    }

    private void initMuteOnScreenOffView(View v) {
        mMuteOnScreenOffTbn = (ToggleButton) v.findViewById(R.id.snd_muteonscreenoff_switch_tbn);
        mMuteOnScreenOffTbn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_muteonscreenoff), "" + mMuteOnScreenOffTbn.isChecked());
                if (mMuteOnScreenOffTbn.isChecked()) {
                    mFlyAudioManager.enableMuteOnScreenOff();
                } else {
                    mFlyAudioManager.disableMuteOnScreenOff();
                }
            }
        });
    }

    private void initMuteOnReverseView(View v) {
        mMuteOnReverseTbn = (ToggleButton) v.findViewById(R.id.snd_muteonreverse_switch_tbn);
        mMuteOnReverseTbn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_muteonreverse), "" + mMuteOnReverseTbn.isChecked());
                if (mMuteOnReverseTbn.isChecked()) {
                    mFlyAudioManager.enableMuteOnReverse();
                } else {
                    mFlyAudioManager.disableMuteOnReverse();
                }
            }
        });
    }

    private void showEqTextView(int val, int id, View v) {
        String show = Integer.toString(val);
        if (val > 0) {
            show = "+" + show;
        }
        TextView tv = (TextView) v.findViewById(id);
        tv.setText(show);
    }

    private void updateMixUI(FlyAudioManager.MixMode mixMode) {
        switch (mixMode) {
            case NAVI_FIRST:
                mMixValueTv.setText(getString(R.string.snd_mix_navi_first));
                mMixListView.setItemChecked(0, true);
                break;
            case NORMAL:
                mMixValueTv.setText(getString(R.string.snd_mix_normal));
                mMixListView.setItemChecked(1, true);
                break;
        }

    }

    private void updateInCallHintUI(final FlyAudioManager.InCallHintMode mode) {
        switch (mode) {
            case TTS:
                mIncomingCallHintTv.setText(getString(R.string.snd_ichint_tts));
                mIchintListView.setItemChecked(0, true);
                break;
            case SYS:
                mIncomingCallHintTv.setText(getString(R.string.snd_ichint_sys));
                mIchintListView.setItemChecked(1, true);
                break;
        }
    }

    private String getBalancePositionAsString(int index, int balance, int fade) {
        final int[] resIds = {R.string.snd_balance_center_best, R.string.snd_balance_lf_best, R.string.snd_balance_rf_best, R.string.snd_balance_lr_best, R.string.snd_balance_rr_best};
        if (index >= 0 && index < resIds.length) {
            return getString(resIds[index]);
        }

        String balanceInfo = "前";
        if (fade <= 0) {
            balanceInfo += "+" + (-fade);
        } else {
            balanceInfo += -fade;
        }
        balanceInfo += " " + "左";
        if (balance <= 0) {
            balanceInfo += "+" + (-balance);
        } else {
            balanceInfo += -balance;
        }

        return balanceInfo;
    }

    private int getBalanceBestIndex(int x, int y) {
        int i;
        for (i = 0; i < mBalanceBestPosition.length; i++) {
            if (x == mBalanceBestPosition[i][0] && y == mBalanceBestPosition[i][1]) {
                return i;
            }
        }
        return i;
    }

    private void updateVolumeUI(TextView volumeTv, SeekBar volumeSb, int v) {
        volumeTv.setText(Integer.toString(v));
        volumeSb.setProgress(v);
    }

    private void updateEqBandUI(int index, int value) {
        if (mEqBandsSb != null && index >= 0 && index < mEqBandsSb.length) {
            synchronized (this) {
                if (mEqBandsSb != null && mEqBandsSb[index] != null) {
                    mEqBandsSb[index].setProgress(value - mEqValMin);
                }
            }
        }
    }

    private void updateEqModeUI(final int mode) {
        mEqModeValueTv.setText(eqModeToResId(mode));
        mEqModeLv.setItemChecked(eqModeToListIdx(mode), true);
    }

    private void updateBalanceUI(boolean updatePannel) {
        updateBalanceUI(updatePannel, mBalanceLogicX, mBalanceLogicY);
    }

    private void updateBalanceUI(final boolean updatePannel, final int x, final int y) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (updatePannel) {
                    mBalancePanel.moveTo(x, y);
                }
                int index = getBalanceBestIndex(x, y);
                mBalanceValTv.setText(getBalancePositionAsString(index, x, y));
                if (index != -1) {
                    mBalanceBestLv.setItemChecked(index, true);
                } else {
                    mBalanceBestLv.setItemChecked(mBalanceBestLv.getCheckedItemPosition(), false);
                }
            }
        });
    }

    private void updateBalanceUIByBest(int index) {
        mBalancePanel.moveTo(mBalanceLogicX, mBalanceLogicY);
        mBalanceValTv.setText(getBalancePositionAsString(index, mBalanceLogicX, mBalanceLogicY));
        if (index != -1) {
            mBalanceBestLv.setItemChecked(index, true);
        } else {
            mBalanceBestLv.setItemChecked(mBalanceBestLv.getCheckedItemPosition(), false);
        }
    }

    private int eqModeToListIdx(int mode) {
        switch (mode) {
            case AudioServiceCons.EQ_MODE.EQ_MODE_CLASSICAL:
                return 2;
            case AudioServiceCons.EQ_MODE.EQ_MODE_DEFAULT:
                return 0;
            case AudioServiceCons.EQ_MODE.EQ_MODE_FASHION:
                return 3;
            case AudioServiceCons.EQ_MODE.EQ_MODE_JAZZ:
                return 1;
            case AudioServiceCons.EQ_MODE.EQ_MODE_ROCK:
                return 4;
        }
        return 5;
    }

    private int eqModeToResId(int mode) {
        switch (mode) {
            case AudioServiceCons.EQ_MODE.EQ_MODE_CLASSICAL:
                return R.string.snd_eq_mode_classic;
            case AudioServiceCons.EQ_MODE.EQ_MODE_DEFAULT:
                return R.string.snd_eq_mode_default;
            case AudioServiceCons.EQ_MODE.EQ_MODE_FASHION:
                return R.string.snd_eq_mode_pop;
            case AudioServiceCons.EQ_MODE.EQ_MODE_JAZZ:
                return R.string.snd_eq_mode_jaz;
            case AudioServiceCons.EQ_MODE.EQ_MODE_ROCK:
                return R.string.snd_eq_mode_rock;
        }
        return R.string.snd_eq_mode_custom;
    }

    private int eqResIdToMode(int id) {
        switch (id) {
            case R.string.snd_eq_mode_default:
                return AudioServiceCons.EQ_MODE.EQ_MODE_DEFAULT;
            case R.string.snd_eq_mode_jaz:
                return AudioServiceCons.EQ_MODE.EQ_MODE_JAZZ;
            case R.string.snd_eq_mode_classic:
                return AudioServiceCons.EQ_MODE.EQ_MODE_CLASSICAL;
            case R.string.snd_eq_mode_pop:
                return AudioServiceCons.EQ_MODE.EQ_MODE_FASHION;
            case R.string.snd_eq_mode_rock:
                return AudioServiceCons.EQ_MODE.EQ_MODE_ROCK;
        }
        return AudioServiceCons.EQ_MODE.EQ_MODE_USER;
    }

    static class UIHandler extends Handler {
        WeakReference<SoundFragment> mFragment;

        UIHandler(SoundFragment f) {
            mFragment = new WeakReference<>(f);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_BALANCE_UI_USER_TOUCH:
                    SoundFragment f = mFragment.get();
                    f.updateBalanceUI(false, msg.arg1, msg.arg2);
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }

    class EQOnSeekBarChangeListener implements VerticalSeekBar.OnSeekBarChangeListener {
        int mBandIndex;
        private boolean mFromUser;

        public void setBandIndex(int i) {
            mBandIndex = i;
        }

        @Override
        public void onProgressChanged(VerticalSeekBar verticalSeekBar,
                                      int progress, boolean fromUser) {
            if (mFromUser) {
                mFlyAudioManager.setEQ(mBandIndex, progress + mEqValMin);
                mFlyAudioManager.setEQMode(AudioServiceCons.EQ_MODE.EQ_MODE_USER);
                saveCustomEq();
            }
        }

        @Override
        public void onStartTrackingTouch(VerticalSeekBar verticalSeekBar) {
            updateEqModeUI(5);
            mFromUser = true;
        }

        @Override
        public void onStopTrackingTouch(VerticalSeekBar verticalSeekBar) {
            mFromUser = false;
            FlowerCollector.onEvent(getActivity().getApplicationContext(), getString(R.string.sound) + "-" + getString(R.string.snd_eq), "seekbar");
        }

    }

}
